package org.geom.curve;

import java.util.ArrayList;

import org.geom.Vector3D;

public abstract class Curve implements ICurve {

	//---------------------------------------------------------------------- statics
	public static int length = 240;

	//---------------------------------------------------------------------- protected
	public ArrayList<Vector3D> points;

	//---------------------------------------------------------------------- abstract
	public abstract Vector3D sample(float t);
	public abstract Vector3D derivateI(float t);
	public abstract Vector3D derivateII(float t);

	//---------------------------------------------------------------------- publics
	public ArrayList<Vector3D> getPoints() {
		float t = 0;
		float dt = this.getArc();

		Vector3D p1 = new Vector3D();

		points = new ArrayList<Vector3D>();
		points.add( sample(0) );
		for(int i=1; i<= Curve.length; i++) {
			p1 = sample(t);
			points.add( p1 );
			t += dt;
		}

		return points;
	}

	public Vector3D tangent(float t) {
		Vector3D tangentVector = derivateI(t);
		tangentVector.normalized();
		if (tangentVector==null) {
			System.out.println("Curve > tangent > derivateI is null");
			return new Vector3D();
		}
		return tangentVector;
	}

	public Vector3D binormal(float t) {
		Vector3D derivataI = derivateI(t);
		Vector3D derivataII = derivateII(t);
		Vector3D binormalVector = derivataI.crossSelf(derivataII);
		binormalVector.normalized();
		/* Il vettore binormale è definito come prodotto vettoriale fra la derivataI e la derivataII.
		 * Il prodotto vettoriale è definito come il prodotto dei moduli per il seno
		 * dell'angolo insito fra i due vettori.
		 * */		
		return binormalVector;
	}

	public Vector3D normal(float t) {
		/*
		 * vettore normale: binormale (prodotto scalare) tangente
		 * */
		return Vector3D.crossProduct(binormal(t), tangent(t));//.normalize();	
	}

	@Override
	public ArrayList<Vector3D> getPointsWithoutResampling() {
		return points;
	}

	//-------------------------------------------------------- 
	public static void setLenght(float n, boolean increment) {
		if(increment)length+=n;
		else length=(int) n;
	}
}
